visualHUD.formGenerator = {
	cache: {},
	createForm: function(_wrapper){
		var form = $('<form class="app-form" />');
		if(_wrapper)
			form.appendTo(_wrapper);
		return form;
	},
	bindFormEvents: function(_form){
		_form.delegate('input,select,button','focus', function(event){
			_form.data('focusedElement', this);
		}).bind('click', function(event){			
			event.stopPropagation();
			if(event.type == 'click'){
				var $target = $(event.target);
				if($target.is('legend')){
					$target.parent().toggleClass('collapsed');
					return false;
				};
			};
		}).submit(function(){
			return false;
		});		
	},
	createFormHeader: function(_data, _form){
		_form.append('<div class="control-header"><div class="header-wrap '+ _data.cssClass +'"><span class="item-type">Item:</span><div class="item-name">'+ _data.label +'</div></div></div>');
		return _form;
	},
	linkForm: function(_form, _element){
		_form.bind('change', function(event){
			var _data = _element.data('HUDItem');
			var name = event.target.name;
			var value = event.target.value;
			var isCheckbox = event.target.type == 'checkbox';
			
			var updateObject = $.extend({}, _data.properties);

			var colorRange = name.match(/colorRange/);
			if(colorRange){
				var rangeData = name.split('_');
				var colorRangeIndex = parseInt(rangeData[1]);
				var currentRange = updateObject.colorRanges[colorRangeIndex];
				
				if(rangeData[2] == 'range') {
					currentRange.range[parseInt(rangeData[3])] = value;
				} else if(rangeData[2] == 'color'){
					currentRange.color = value;
				};
			};
			
			if(!colorRange) {
				//value = name.match(/width|height/) ? value * visualHUD.scaleFactor : value;
				updateObject[name] = isCheckbox ? event.target.checked : value;
			};
			
			if(name) {
				visualHUD.application.getItemStatus(_element,_data);
				visualHUD.application.setupHudItem[_data.properties.itemType](_element, _data, updateObject);
			};

/*			visualHUD.application.actionsStack.push({
				element: _element,
				properties: updateObject,
				form: _form
			});*/
		});
		
	},
	createFieldset: function(_name, _form){
		var fieldset = $('<fieldset></fieldset>');
		if(_name){
			fieldset.append('<legend>'+ _name +'</legend>');
		};
		fieldset.appendTo(_form);
		
		return fieldset;
	},
	createActionsPanel: function(_name, _form){
		var fieldset = $('<fieldset class="form-actions"><ul class="app-toolbar"></ul></fieldset>');
		if(_name){
			fieldset.append('<legend>'+ _name +'</legend>');
		};
		fieldset.appendTo(_form);
		
		return fieldset.find('ul.app-toolbar');
	},
	createTextBox: function(_data, _form){
		var template = '<span class="f-label">{0}</span><span class="f-inputs">\
							<input type="text" size="{3}" name="{1}" value="{2}" maxlength="{4}"  />\
						</span>';
					
		var wrap = $('<div class="f-row" />');
		wrap.html(template.format(_data.label, _data.name, _data.value || '', _data.size || 32, _data.maxlength || '')).appendTo(_form);
		return wrap;
	},
	createRangeInput: function(_data, _form){
		
		var template = '<span class="f-label">{0}</span><span class="f-inputs">\
							<div class="slider"><div class="progress"></div><input type="button" class="handle" /></div> <input type="text" size="8" maxlength="3" class="range range-input" name="{1}"  />\
						</span>';
		var rangeInputData = {
			min: _data.min,
			max: _data.max,
			value: _data.value,
			precision: false,
			keyboard: false,
			progress: true,
			sliderSize: 180,
			handleSize: 12
		};

		var wrap = $('<div class="f-row" />');
	
		wrap.html(template.replace(/\t/g,'').format(_data.label, _data.name)).appendTo(_form);
		var input = wrap.find('input.range-input').rangeinput(rangeInputData);

		return wrap;
	},
	bindRangeInput: function(_data, _input){
		_input.attr({
			maxlength: 3,
			size: 8
		}).rangeinput({
			min: _data.min,
			max: _data.max,
			value: _data.value,
			precision: false,
			keyboard: false,
			progress: true
		}).focus(function(){ });

		return _input;
	},	
	createCheckbox: function(_data, _form){
		var template = '<div class="f-inputs f-checkboxes">\
							<label class="check-label"><input type="checkbox" name={0} {1}><span class="label">{2}</span></label>\
						</div>';
					
		var wrap = $('<div class="f-row" />');
		wrap.html(template.format(_data.name, _data.value ? 'checked="checked"' : '', _data.label)).appendTo(_form);
		return wrap;		
	},
	createRadioButtons: function(_data, _form){
	},
	createSelect: function(_data, _form){
		var template = '<span class="f-label">{0}</span><span class="f-inputs">\
							<select name="{1}">{2}</select>\
						</span>';
		
		
		var optionHTMLTemplate = '<option value="{0}">{1}</option>';
		var optgroupHTMLTemplates = ['<optgroup label="{0}">', '</optgroup>'];
		var index = 0;
		var selectHTML = [];
		
		var generateSelectOptions = function(opts){
			
			var option;
			for(var a in opts){
				option = opts[a];
				if($.isPlainObject(option)){
					selectHTML.push(optgroupHTMLTemplates[0].format(a));
					generateSelectOptions(option);
					selectHTML.push(optgroupHTMLTemplates[1]);
				} else {
					selectHTML.push(optionHTMLTemplate.format(a, option));
				};
			};
			return selectHTML.join('')
		};

		var wrap = $('<div class="f-row" />');
		wrap.html(template.format(_data.label, _data.name, generateSelectOptions(_data.options) )).appendTo(_form);
		
		var selectElement = wrap.find('select');
		selectElement.css('width', _data.width || 'auto');

		if(_data.value)
			selectElement.val(_data.value);
		else 
			selectElement.get(0).selectedIndex = 0;


		return wrap;
	},
	createButton: function(_data, _form){
		var template = '<button  name="{0}" value="{1}" class="{2}" title="{3}"><span class="{4}">{5}</span></button>';
		var icon =  _data.icon ? 'w-icon ' +  _data.icon : '';
		var wrap = $(template.format(_data.name, _data.label, _data.cssClass || '', _data.tooltip || '', icon, _data.label)).appendTo(_form);
		
		wrap.click(function(){
			return _data.fn.apply(visualHUD.application, _data.args || []);
		});
		
		return wrap;
	},
	createToolbarButton: function(_data, _form){
		var template = '<li class="{0}"><span class="item-name">{1}</span><strong class="item-value hidden"></strong></li>';
		var icon =  _data.icon || '';
		var wrap = $(template.format(_data.icon, _data.label)).appendTo(_form);
		
		wrap.click(function(){
			return _data.fn.apply(visualHUD.application, _data.args || []);
		});
		
		return wrap;
	},
	createAlignControl: function(_form){
		var template = '<span class="f-label">Align</span><span class="f-inputs"></span>';
		var wrap = $('<div class="f-row" />').html(template).appendTo(_form);
		$('#alignControls').clone(true).attr('id', '').appendTo(wrap.find('.f-inputs'));
		return wrap;
	},
	createArrangeControl: function(_form){
		var template = '<span class="f-label">Arrange</span><span class="f-inputs"></span>';
		var wrap = $('<div class="f-row" />').html(template).appendTo(_form);		
		$('#arrangeControls').clone(true).removeClass('hidden').appendTo(wrap.find('.f-inputs'));
		return wrap;
	},
	createStyleButtons: function(_data, _form){
		var template = '<span class="f-label">Style</span><span class="f-inputs"></span>';
		var wrap = $('<div class="f-row" />').html(template).appendTo(_form);
		var buttonsWrap = wrap.find('.f-inputs');
		this.createButton({
			'name': 'copy_style',
			'label': 'Copy',
			'cssClass': 'button-small mr-5',
			'icon': '',
			'fn': visualHUD.application.copyProperties,
			'args': [_data.element]
		}, buttonsWrap);

		var applyStyleButton = this.createButton({
			'name': 'apply_style',
			'label': 'Apply',
			'cssClass': 'button-small mr-5',
			'icon': '',
			'fn': visualHUD.application.applyProperties,
			'args': [_data.element]
		}, buttonsWrap);
		
		visualHUD.application.styleButtons.push(applyStyleButton.attr('disabled', !visualHUD.application.elementPropsClipboard).get(0));
	},
	createColorPicker: function(_data, _form){
		this.setupColorPicker();
		
		var wrap = this.createTextBox(_data, _form);		
		var input = wrap.find('input[type=text]');
		
		var colorPickerDIV = $('<div class="color-picker-box" />')
			.css('backgroundColor', '#' + _data.value)
			.insertAfter(input).click(function(event){
				visualHUD.formGenerator.colorpicker.colorInput = input;
				visualHUD.formGenerator.colorpicker.show($(this), event);
				return false;
			});
		if(_data.hint) {
			colorPickerDIV.clone().attr('class', 'color-picker-hint').css('backgroundColor', '').insertAfter(colorPickerDIV).html(_data.hint);
		}
		
		input.change(function(){
			var color = $.color('#' + this.value);
			colorPickerDIV.css('backgroundColor', color.hex);
		});
		
		return wrap;
	},
	setupColorPicker: function(){
		var $body = $(document.body);
		
		this.colorpicker = this.colorpicker || new xpk.DHTMLArea(visualHUD.application.settingsArea,{
			delegate: true,
			fromSelector: 'div.color-picker-box',
			className: 'color-picker-wrapper clearfloat',
			init: function(){
				var _this = this;
				this.palette = visualHUD.constructor.colorPresets;
				
				for(var a = 0, b = this.palette.length; a<b; a++){
					this.palette[a] = this.palette[a].toUpperCase();
					this.menu.append('<div class="color-cell" style="background-color:'+ "#"+this.palette[a] +'"></div>');
				};
				
				this.paletteElements = this.menu.find('div.color-cell');
				var preventMouseleave = false;
				
				this.menu.bind('mouseover mouseout click', function(event){
					if(_this.activeElement) {
						var $target = $(event.target);
						var $colorCell = $target.closest('div.color-cell');
						
						if($colorCell.length) {
							var color = $colorCell.css('backgroundColor');
							var initialColor = $.color(color);
							
							var classFoo = event.type == 'mouseout' || event.type == 'click' ? 'removeClass' : 'addClass';
							
							if (event.type == 'mouseover') {
								_this.$activeElement.css('backgroundColor', color);
								color = $.color(color);
								_this.colorInput.val(color.hex.replace('#','').toUpperCase());
							} else if(event.type == 'mouseout'){
								if(!preventMouseleave) {
									_this.colorInput.val(_this.backgroundColor.hex.replace('#','').toUpperCase());
									_this.$activeElement.css('backgroundColor', _this.backgroundColor.hex);
								};
							}
							
							$colorCell[classFoo]('color-cell-hover');
							
							if(event.type == 'click') {
								preventMouseleave = true;
								_this.colorInput.trigger('change');
								_this.hide();
								return false;
							};
							preventMouseleave = false;
						};				
					};
				});
				
			},
			onshow: function(){
				this.backgroundColor = $.color(this.$activeElement.css('backgroundColor'));
				var currentIndex = $.inArray(this.backgroundColor.hex.replace('#','').toUpperCase(), this.palette);
				this.currentColorCell = this.paletteElements.eq(currentIndex).addClass('active-color');
				$body.addClass('color-picker-active');
			},
			onhide: function(){
				this.currentColorCell.removeClass('active-color');
				window.setTimeout(function(){
					$body.removeClass('color-picker-active');
				}, 10);
			}
		})		
	},
	createColorRange: function(_ranges, _form){
		var colors = visualHUD.constructor.colorRangeColors;
		var ranges = visualHUD.constructor.colorRangeValues;

		var cp = $();
		
		for(var a = 0, b = _ranges.length; a < b; a++){
			var range = _ranges[a];
			var cpicker = visualHUD.formGenerator.createColorPicker({
				'name': 'colorRange_' + a + '_color',
				'label': range.name,
				'size': 6,
				'maxlength': 6,
				'value': range.color,
				'hint': null //range.range.join(' - ')
			}, _form);
			
			cp = cp.add(cpicker);
			
			var input = cpicker.find('input[type=text]');
			var span = $('<span class="color-range-inputs mr-10" />').insertBefore(input);
			
			input.clone().appendTo(span).attr({
				'class': 'color-range-input mr-5',
				'name': 'colorRange_' + a + '_range_0',
				'size': 3,
				'maxlength': 3,
				'value': range.range[0]
			});
			
			input.clone().appendTo(span).attr({
				'class': 'color-range-input mr-5',
				'name': 'colorRange_' + a + '_range_1',
				'size': 3,
				'maxlength': 3,
				'value': range.range[1]
			});
		};

		var rangeValueInputs = _form.find('input.color-range-input');
			
		_form.delegate('input[type=text]', 'change', function(event){
			var $input = $(this),
				index = rangeValueInputs.index(this),
				odd = (index + 1) % 2 == 0,
				value;
			
			var $nextInput = rangeValueInputs.eq(index + 1),
				$prevInput = rangeValueInputs.eq(index - 1);
			
			if(odd){
				value = parseInt(this.value);
				if($nextInput.length && !$nextInput.attr('readOnly')){
					$nextInput.val(value + 1);
				}
			} else {
				value = parseInt(this.value);
				if($prevInput.length && !$prevInput.attr('readOnly')){
					$prevInput.val(value - 1);
				}
			}
		});
					
		rangeValueInputs.first().attr('readonly', true);
		rangeValueInputs.last().attr('readonly', true);
		
		return cp;
	},

	createSimpleColorRange: function(_ranges, _form){
		var rangeColors = visualHUD.constructor.colorRangeColors;
		var ranges = visualHUD.constructor.colorRangeValues;

		var colors = visualHUD.constructor.simpleColorPresets
		var colorNames = ['Red', 'Lime', 'Yellow', 'Blue', 'Cyan', 'Magenta', 'White', 'Black'];
		
		var colorSelectOptions = {};
		
		$.each(colors, function(i){
			colorSelectOptions[String(i+1)] = colorNames[i];
		});
		
		var rangeValueInputs = [];
		
		var cp = $();
		
		$.each(_ranges, function(a){

			var range = this;
			var colorSelectName = 'colorRange_' + a + '_color';
			var colorSelectControl = visualHUD.formGenerator.createSelect({
					'name': colorSelectName,
					'label': range.name,
					'value': range.color,
					'width': '80px',
					'options': colorSelectOptions
				}, _form);

			colorSelect = colorSelectControl.find('select[name=' + colorSelectName + ']' );
			colorSelect.css({'verticalAlign': 'middle'}).addClass('ml-5');
			
			var colorPickerDIV = $('<div class="color-picker-box" />')
				.insertBefore(colorSelect).click(function(event){
					colorSelect.focus();
					return false;
				});
		
			colorSelect.bind('change', function(){
				var color = parseInt(this.value) - 1;
				color = visualHUD.constructor.simpleColorPresets[color];
				colorPickerDIV.css('backgroundColor', '#' + color);
			});
			
			colorSelect.trigger('change');
			
			cp = cp.add(colorSelectControl);
			
			var span = $('<span class="color-range-inputs mr-10" />').insertBefore(colorPickerDIV);
			var input = $('<input type=text />');
			
			rangeValueInputs.push(input.appendTo(span).attr({
				'class': 'mr-5',
				'name': 'colorRange_' + a + '_range_0',
				'size': 3,
				'maxlength': 3,
				'value': range.range[0]
			}));


			rangeValueInputs.push(input.clone().appendTo(span).attr({
				'class': 'mr-5',
				'name': 'colorRange_' + a + '_range_1',
				'size': 3,
				'maxlength': 3,
				'value': range.range[1]
			}));
		
		});
		
		rangeValueInputs[0].attr('readonly', true);
		rangeValueInputs[rangeValueInputs.length-1].attr('readonly', true);
		
		return cp;
	}	
};